#include <ConfigInit.h>
/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-07-03     ThinkPad       the first version
 */
#include <rtthread.h>
#include <sys/socket.h>
#include "netdb.h"
#include <netdev.h>
#include <string.h>
#include "ConfigInit.h"

#define BUF_SIZE_UDP    (1024)

static int s_nUdpDataLen = 50;
static int s_nUdpCurLen = 0;
static int sock;
static int bytes_read;
rt_uint8_t* recv_data;
socklen_t addr_len;
struct sockaddr_in server_addr, client_addr;

extern struct rt_semaphore g_sem_sd;

static int s_fd;

static char* s_formats[32] = {
        "/udp_data/%d%d%d_%d%d%d",
        "/udp_data/%d%d%d_%d%d0%d",
        "/udp_data/%d%d%d_%d0%d%d",
        "/udp_data/%d%d%d_%d0%d0%d",
        "/udp_data/%d%d%d_0%d%d%d",
        "/udp_data/%d%d%d_0%d%d0%d",
        "/udp_data/%d%d%d_0%d0%d%d",
        "/udp_data/%d%d%d_0%d0%d0%d",
        "/udp_data/%d%d0%d_%d%d%d",
        "/udp_data/%d%d0%d_%d%d0%d",
        "/udp_data/%d%d0%d_%d0%d%d",
        "/udp_data/%d%d0%d_%d0%d0%d",
        "/udp_data/%d%d0%d_0%d%d%d",
        "/udp_data/%d%d0%d_0%d%d0%d",
        "/udp_data/%d%d0%d_0%d0%d%d",
        "/udp_data/%d%d0%d_0%d0%d0%d",
        "/udp_data/%d0%d%d_%d%d%d",
        "/udp_data/%d0%d%d_%d%d0%d",
        "/udp_data/%d0%d%d_%d0%d%d",
        "/udp_data/%d0%d%d_%d0%d0%d",
        "/udp_data/%d0%d%d_0%d%d%d",
        "/udp_data/%d0%d%d_0%d%d0%d",
        "/udp_data/%d0%d%d_0%d0%d%d",
        "/udp_data/%d0%d%d_0%d0%d0%d",
        "/udp_data/%d0%d0%d_%d%d%d",
        "/udp_data/%d0%d0%d_%d%d0%d",
        "/udp_data/%d0%d0%d_%d0%d%d",
        "/udp_data/%d0%d0%d_%d0%d0%d",
        "/udp_data/%d0%d0%d_0%d%d%d",
        "/udp_data/%d0%d0%d_0%d%d0%d",
        "/udp_data/%d0%d0%d_0%d0%d%d",
        "/udp_data/%d0%d0%d_0%d0%d0%d"
};


static void UdpServer_thread_entry(void *parameter)
{
    rt_kprintf("waiting for sem sd from UdpServer\n");
    rt_sem_take(&g_sem_sd, RT_WAITING_FOREVER);

    rt_kprintf("get sem sd from UdpServer\n");


    cJSON* root = getComConfigRoot();
    cJSON* myComInfo = cJSON_GetArrayItem(root, 5);  // get udp data len
    s_nUdpDataLen = cJSON_GetObjectItem(myComInfo, "len")->valueint;

    rt_kprintf("s_nUdpDataLen: %d\n", s_nUdpDataLen);

    time_t now = time(RT_NULL);
    rt_kprintf("in udpInit %s\n", ctime(&now));

    rt_kprintf("asctime %s\n", asctime(gmtime(&now)));

    struct tm *p = localtime(&now);
    char strTime[32];

    int nFormatIndex = 16*(int)((1+p->tm_mon)<10) + 8*(int)((p->tm_mday)<10) + 4*(int)((p->tm_hour)<10) + 2*(int)((p->tm_min)<10) + (int)((p->tm_sec)<10);
    rt_kprintf("nFormatIndex: %d", nFormatIndex);

    rt_kprintf("format %s: ", s_formats[nFormatIndex]);

    sprintf(strTime, s_formats[nFormatIndex], (1900+p->tm_year),
            (1+p->tm_mon),
            p->tm_mday,
            p->tm_hour,
            p->tm_min,
            p->tm_sec);

    rt_kprintf("asctime 2  %s\n", strTime);


    s_fd = open(strTime, O_WRONLY | O_APPEND | O_CREAT);


    recv_data = rt_malloc(BUF_SIZE_UDP);
    if (RT_NULL == recv_data)
    {
        rt_kprintf("malloc memory failed\n");
        return;
    }

    if (-1 == (sock = socket(AF_INET, SOCK_DGRAM, 0)))
    {
        rt_kprintf("create sock error\n");
        rt_free(recv_data);
        return;
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(5000);
    server_addr.sin_addr.s_addr = INADDR_ANY;
    rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));

    if (-1 == bind(sock, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)))
    {
        rt_kprintf("bind sock error\n");
        rt_free(recv_data);
        return;
    }

    addr_len = sizeof(struct sockaddr);
    rt_kprintf("UdpServer waiting for client on port 5000...\n");

    while (1)
    {
        /* 从sock中收取最大BUFSZ - 1字节数据 */
        bytes_read = recvfrom(sock, recv_data, BUF_SIZE_UDP - 1, 0,
                              (struct sockaddr *)&client_addr, &addr_len);


        rt_kprintf("bytes_read: %d\n", bytes_read);

        write(s_fd, recv_data, bytes_read);
        fsync(s_fd);

        s_nUdpCurLen += bytes_read;
//        if (s_nUdpCurLen >= s_nUdpDataLen*1024*128)
            if (s_nUdpCurLen >= 1024)
        {
            s_nUdpCurLen = 0;
            // create a new file
            close(s_fd);
            int nFormatIndex = 16*(int)((1+p->tm_mon)<10)
                    + 8*(int)((p->tm_mday)<10)
                    + 4*(int)((p->tm_hour)<10)
                    + 2*(int)((p->tm_min)<10)
                    + (int)((p->tm_sec)<10);

            sprintf(strTime, s_formats[nFormatIndex], (1900+p->tm_year),
                    (1+p->tm_mon),
                    p->tm_mday,
                    p->tm_hour,
                    p->tm_min,
                    p->tm_sec);

            s_fd = open(strTime, O_WRONLY | O_APPEND | O_CREAT);
        }

        /* UDP不同于TCP，它基本不会出现收取的数据失败的情况，除非设置了超时等待 */
//        recv_data[bytes_read] = '\0'; /* 把末端清零 */
//        /* 输出接收的数据 */
//        rt_kprintf("\n(%s , %d) said : ", inet_ntoa(client_addr.sin_addr),
//                   ntohs(client_addr.sin_port));
//        rt_kprintf("%s", recv_data);
//        /* 如果接收数据是exit，退出 */
//        if (strcmp(recv_data, "exit") == 0)
//        {
//            closesocket(sock);
//            /* 释放接收用的数据缓冲 */
//            rt_free(recv_data);
//            break;
//        }
    }
}



int UdpInit()
{
    struct netdev *netdev = RT_NULL;
    ip_addr_t addr;
    ip_addr_t netmask;
    ip_addr_t gw;


    /* 通过名称获取网卡对象 */
    netdev = netdev_get_by_name("e0");
    if (netdev == RT_NULL)
    {
        rt_kprintf("input network interface name(w0) error.\n");
        return -1;
    }

    /*  设置DHCP */
    netdev_dhcp_enabled(netdev,RT_FALSE);


    /*  设置网卡 IP 地址*/
    inet_aton("192.168.21.30", &addr);
    inet_aton("192.168.21.1", &gw);
    netdev_set_ipaddr(netdev, &addr);
    netdev_set_gw(netdev, &gw);
    inet_aton("255.255.255.0", &netmask);
    netdev_set_netmask(netdev,&netmask);


    rt_kprintf("ip\n");
    rt_kprintf("ip: %ud\n", netdev_default->ip_addr.addr);
    rt_kprintf("ipipip\n");
    rt_err_t ret = RT_EOK;



    /* 创建 serial 线程 */
    rt_thread_t thread = rt_thread_create("tUdp", UdpServer_thread_entry, RT_NULL, 2048, 26, 10);
    /* 创建成功则启动线程 */
    if (thread != RT_NULL)
    {
        rt_kprintf("start udp thread ok\n");
        rt_thread_startup(thread);
    }
    else
    {
        rt_kprintf("start udp thread failed\n");
        ret = RT_ERROR;
    }











//
//    recv_data = rt_malloc(BUF_SIZE_UDP);
//     if (RT_NULL == recv_data)
//     {
//         rt_kprintf("malloc memory failed\n");
//         return;
//     }
//
//     if (-1 == (sock = socket(AF_INET, SOCK_DGRAM, 0)))
//     {
//         rt_kprintf("create sock error\n");
//         rt_free(recv_data);
//         return;
//     }
//
//     server_addr.sin_family = AF_INET;
//     server_addr.sin_port = htons(15000);
//     server_addr.sin_addr.s_addr = INADDR_ANY;
//     rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
//
//     if (-1 == bind(sock, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)))
//     {
//         rt_kprintf("bind sock error\n");
//         rt_free(recv_data);
//         return;
//     }
//
//     addr_len = sizeof(struct sockaddr);
//     rt_kprintf("UdpServer waiting for client on port 15000...\n");
//
//    while (1)
//    {
//        rt_kprintf("1111111\n\n");
//        /* 从sock中收取最大BUFSZ - 1字节数据 */
//        bytes_read = recvfrom(sock, recv_data, BUF_SIZE_UDP - 1, 0,
//                              (struct sockaddr *)&client_addr, &addr_len);
//
//        rt_kprintf("222222\n\n");
//        /* UDP不同于TCP，它基本不会出现收取的数据失败的情况，除非设置了超时等待 */
//        recv_data[bytes_read] = '\0'; /* 把末端清零 */
//        /* 输出接收的数据 */
//        rt_kprintf("\n(%s , %d) said : ", inet_ntoa(client_addr.sin_addr),
//                   ntohs(client_addr.sin_port));
//        rt_kprintf("%s", recv_data);
//        /* 如果接收数据是exit，退出 */
//        if (strcmp(recv_data, "exit") == 0)
//        {
//            closesocket(sock);
//            /* 释放接收用的数据缓冲 */
//            rt_free(recv_data);
//            break;
//        }
//    }



    return ret;
}





